import multiprocessing
from  multiprocessing import Process, Value, Array, Manager, Queue, Pipe

'''
# 子进程的修改，不会同步到主进程




def task(data):
    data.append(666)
    print("子进程：", data)


if __name__ == '__main__':
    data_list = []
    p = Process(target=task, args=(data_list,))
    p.start()
    p.join()
    print("主进程：", data_list)
    
'''

"""
# 共享方式： Value or Array
# 
# 'c': ctypes.c_char,'u': ctypes.c wchar,
# 'b': ctypes.c byte,'B': ctypes.clubyte,
# 'h': ctypes.c short,'H': ctypes.c ushort,
# 'i': ctypes.c int,'I': ctypes.c uint,
# '1': ctypes.c long,'L': ctypes.c ulong,
# 'f': ctypes.c float,'d': ctypes.c double



def func(n, m1, m2, arr1, arr2):
    n.value = 888
    m1.value = 'a'.encode("utf-8")
    m2.value = "武"
    arr1[0] = 111
    arr2[0] = False


if __name__ == '__main__':
    num = Value('i', 666)
    m1 = Value('c')
    m2 = Value('u')
    # array 只支持integer和byte
    arr1 = Array('i', [11, 22, 33]) # 定义后不能追加；元素类型也不能改变
    arr2 = Array('b', [True, True, True])  # 定义后不能追加；元素类型也不能改变
    print(num.value)
    print(m1.value)
    print(m2.value)
    print(arr1[:], arr2[:])

    p = Process(target=func, args=(num, m1, m2, arr1, arr2))
    p.start()
    p.join()

    print(num.value)
    print(m1.value)
    print(m2.value)
    print(arr1[:], arr2[:])
"""
"""
manager 支持 字典和列表 of python objects，
queue 队列 队列中可以放 python objects
pipe 像 socket 通信 
"""


def f(d, l, q, child_conn):
    d["name"] = "tony"
    d["age"] = 30
    l.append(666)
    l.append("helloWord")
    q.put("son of bitch")
    for i in range(3):
        q.put(i)
    child_conn.send("888")
    data = child_conn.recv()
    print("子进程接收：", data)


if __name__ == '__main__':
    with Manager() as manager:
        queue = Queue()
        parent_conn, child_conn = Pipe()
        d = manager.dict()
        l = manager.list()
        p = Process(target=f, args=(d, l, queue, child_conn))
        p.start()
        # 因为存在阻塞且是双向，必须在join前；或没有join,以免相互影响
        info = parent_conn.recv()  # 阻塞
        print("主进程接收：", info)
        parent_conn.send("666")
        p.join()

        print(d)
        print(l)
        print(queue.get())
        print(queue.get())
        print(queue.get())

"""
其它方式：基于数据库或文件；如redis会用得比较多
--> Manager, Queue, Redis 使用得多
"""